package com.alibaba.serverless.service.handle;

import com.alibaba.serverless.common.constant.SmtpServiceConstants;
import com.alibaba.serverless.common.exception.BizException;
import com.alibaba.serverless.common.util.RedisUtils;
import com.alibaba.serverless.common.util.StringUtils;
import com.alibaba.serverless.common.util.io.IoUtils;
import com.alibaba.serverless.dao.SmtpConfigDao;
import com.alibaba.serverless.dao.SmtpTemplateDao;
import com.alibaba.serverless.dao.impl.ISmtpConfigDaoImpl;
import com.alibaba.serverless.dao.impl.ISmtpTemplateDaoImpl;
import com.alibaba.serverless.domain.ReceiveParams;
import com.alibaba.serverless.domain.SmtpConfig;
import com.alibaba.serverless.domain.SmtpTemplate;
import com.aliyuncs.dm.model.v20151123.BatchSendMailRequest;
import com.aliyuncs.dm.model.v20151123.SingleSendMailRequest;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;

/**
 * 邮件策略
 * @author mac_zyj
 */
public abstract class BaseSmtpStrategy {
    protected final Logger logger = LoggerFactory.getLogger(BaseSmtpStrategy.class);
    protected static final Integer  ONE_DAY = 60 * 60 * 24;
    protected static final Integer ONE_MINE = 60;
    protected static final Integer ONE_HOUR = 60 * 60;
    protected final SmtpTemplateDao smtpTemplateDao =new ISmtpTemplateDaoImpl();
    protected final SmtpConfigDao smtpConfigDao =new ISmtpConfigDaoImpl();
    protected final RedisUtils redisService=new RedisUtils();
    /**
     * 生成简单邮件请求
     * @param smtpParams 邮件参数
     * @return 简单邮件对象
     */
    public abstract SingleSendMailRequest sendSingleMailRequest(ReceiveParams smtpParams);

    /**
     * 生成模板邮件请求
     * @return 模板邮件请求
     */
    public abstract BatchSendMailRequest sendBatchMailRequest();

    /**
     * 通过OSS软链接方式获取Html发送体内容
     * @param fileKey
     * @param url
     * @return
     */
    protected String getHtmlBodyByUrl(String fileKey,String url)  {
        try{
            InputStream mailTemplateStream = checkCacheAndGetInput(fileKey,url);
            return getInputStreamToHtmlBody(mailTemplateStream);
        }catch (MalformedURLException urlException){
            logger.warn("malformed url exception:{}", ExceptionUtils.getStackTrace(urlException));
            throw new BizException("路径解析失败！");
        } catch (IOException ioException) {
            logger.warn("IO exception:{}",ExceptionUtils.getStackTrace(ioException));
            throw new BizException("OI异常！");
        }
    }

    private InputStream checkCacheAndGetInput(String fileKey,String url) throws IOException {
        String cacheResult = redisService.get(fileKey);
        if (StringUtils.isNotEmpty(cacheResult)){
            redisService.setEx(fileKey, ONE_DAY,cacheResult);
        }
        else {
            // 上传网络流。
            cacheResult =new String(IoUtils.toByteArray(new URL(url).openStream()));
            redisService.setEx(fileKey,3*ONE_DAY,cacheResult);
        }
        return new ByteArrayInputStream(cacheResult.getBytes());
    }


    private String getInputStreamToHtmlBody(InputStream mailTemplateStream){
        Scanner scanner = new Scanner(mailTemplateStream);
        StringBuilder htmlBody = new StringBuilder();
        while (scanner.hasNextLine()) {
            //去除空格 否则调用接口会报异常
            String currentLine= scanner.nextLine().replace("  ", "");
            htmlBody.append(currentLine);
        }
        return htmlBody.toString();
    }

    protected SingleSendMailRequest initSingleSendMail(ReceiveParams smtpParams){
        SmtpConfig smtpConfig=smtpConfigDao.selectSmtpConfigByName(smtpParams.getConditionName());
        SmtpTemplate smtpTemplate=smtpTemplateDao.selectTemplateByName(smtpParams.getConditionName());
        SingleSendMailRequest request=smtpConfig.initNoReplyRequest();
        request.setToAddress(smtpParams.getToAddress());
        request.setSubject(smtpTemplate.getTitle());
        smtpParams.setFileKey(smtpTemplate.getFileName()+smtpTemplate.getVersion());
        smtpParams.setFileLocation(smtpTemplate.getTemplateLocal());
        return request;
    }
}
